import json
import requests
import unittest
import pymysql


class PublicCc(unittest.TestCase):

    env = 'test'
    token_file = 'C:\Sessionid&Token.json'
    config = {
        'test':{'url': 'https://cc-test.b2bwings.com', 'phone': 15000000004, 'pw': '123456',    'org_name':None},
        'uat': {'url': 'https://cc-uat.b2bwings.com',  'phone': 17500000003, 'pw': 'zj123456@', 'org_name':None},
        'pro': {'url': 'https://nccw.gdagri.gov.cn',   'phone': 17346642256, 'pw': 'zj123456@', 'org_name':None}
    }
    pw = config[env]['pw']
    url = config[env]['url']
    phone = config[env]['phone']
    org_name = config[env]['org_name']

    def get_orgid(self, org_name, phone):
        '''获取账号下组织机构的id,org_name是组织名,不传则默认是第一个组织'''
        data = {"account": phone, "check": False}
        head = {'Content-Type': 'application/json'}
        full_url = self.url + '/api/core/v1/login/getAuthenticationOrg'
        res = requests.post(full_url, json=data, headers=head, verify=False).json()
        self.assertEqual(res['message'], '操作成功', f'手机号和组织：{phone,org_name}')
        if org_name:
            for i in res['data']:
                if i['organizationName'] == org_name:
                    org_id = i['sysOrganizationId']
                else:
                    org_id = None
        else:
            org_id = res['data'][0]['sysOrganizationId']
        self.assertIsNotNone(org_id, f'账号({phone})下没有该组织机构({org_name})')
        return org_id

    def get_token(self, phone, pw, org_name, new_token):
        '''获取token方法,new_token是否获取新的token'''
        head = {'Content-Type': 'application/json'}
        token_key = f'{self.url, phone, self.org_name}'
        if new_token:
            full_url = self.url + '/api/core/v1/login/authentication'
            data = {"account": phone,
                     "sysOrganizationId": self.get_orgid(org_name, phone),
                     "password": pw,
                     "check": False,
                     "channel": 1}
            res = requests.post(full_url, json=data, headers=head, verify=False).json()
            token = res['data']['token']
            # 每次获取新token时都进行更新保存（先读取json用于追加或更新，如果json不存在或内容非json格式则赋值为{}）
            try:
                with open(self.token_file, 'r', encoding='utf-8') as file:
                    json_data = json.load(file)
            except (FileNotFoundError, json.JSONDecodeError):
                json_data = {}
            with open(self.token_file, 'w', encoding='utf-8') as file:
                json_data.update({token_key: token})
                json.dump(json_data, file, indent=4, ensure_ascii=False)
        else:
            try:
                with open(self.token_file, 'r', encoding='utf-8') as file:
                    token = json.load(file)[token_key]
            except:
                token = self.get_token(phone, pw, org_name, new_token=True)
        return token

    def post(self, api, data, phone=phone, pw=pw, org_name=org_name, new_token=False ):
        for i in range(2):
            head = {
                    'Content-Type': 'application/json',
                    'token': self.get_token(phone, pw, org_name, new_token)
                   }
            res = requests.post(
                url = self.url + api,
                json = data,
                headers = head,
                verify = False
            ).json()
            if res['message'] == '需要登录!':
                self.get_token(phone, pw, org_name, new_token=True)
            else:
                break
        self.assertEqual(res['message'], '操作成功', f'环境{self.env},接口{api},传参{data}')
        return res

    def get_bookid(self, book_name):
        '''根据账套名获取账套id'''
        api = '/api/core/v1/sysOrganization/getChildrenSysOrganizationList'
        code = self.post(api,{})['data'][0]['sysOrganizationGroupCode']
        # 搜索账套，并获取账套id
        api = '/api/core/v1/selectAccountBook/getAccountBookList'
        data = {
                "searchWord": book_name,
                "sysOrganizationGroupCode": code
                }
        res = self.post(api, data)['data']['records']
        self.assertTrue(res, f'{self.phone,self.org_name}该账号下没有查询到该账套：{book_name}')
        bookid = res[0]['baseAccountBookId']
        return bookid

    def run_sql(self, sql, database='cc-core',env='test'):
        '''公共方法：封装执行数据库语句，database是数据库名'''
        # 判断是uat还是测试环境，连接不同的数据库
        if env=='test':
            mysql = pymysql.connect(
                host='47.107.130.89',
                user='b2bwings',
                password='b2bwings3018',
                port=3306,
                database=database)
        else:
            mysql = pymysql.connect(
                host='47.107.81.143',
                user='b2bwings',
                password='b2bwings666!',
                port=3306,
                database=database)
        cursor = mysql.cursor()
        try:
            cursor.execute(sql)
            mysql.commit()
            if cursor.description:  # 获取数据库字段名称及其他信息，None的话则不是查询语句所以不用执行下面操作
                keys = [column[0]
                        for column in cursor.description]  # 从所有信息中获取字段名称
                values = cursor.fetchall()  # 按照顺序获取到执行sql语句后的数据库值
                if values == ():
                    return None
                else:
                    dict1 = dict(zip(keys, values[0]))  # 以字典的形式返回查询数据的第一条数据
                    return dict1
        except Exception as e:
            mysql.rollback()
            self.assertIsNone(e)
        cursor.close()
        mysql.close()
